/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "ui文本编辑.h"
#include "系统/系统平台.h"

#include <字符串/str_分割.h>
#include <面/面.h>
#include "core/属性.h"



DEF_单色绘制ID(光标);


//static bool 选择开启 = false;
static vec2 选择开始位置 = {};
static vec2 选择结束位置 = {};

static vec2 鼠标开始位置 = {};
static vec2 鼠标结束位置 = {};

static bool g文本框选 = false;



static void f_行编辑框Draw(C_Widget* self, S_2D画布* 画布) {
	C_行编辑框* box = (C_行编辑框*)(self);
	box->m_框部件.m_属性 = f_vg_gen属性(画布);
	
	S_凸边图元 图元 = {};
	图元.属性 = f_vg_get属性指针(画布, box->m_框部件.m_属性);
	box->m_框部件.f_Draw(画布, 图元, E_笔刷类型::e_单色填充);


	图元 = {};
	图元.属性 = f_vg_get属性指针(画布, box->m_框部件.m_属性);
	if (box->m_Value.m_Type == E_值类型::e_Type_Str && box->m_Value.m_UI->m_部件) {
		C_行编辑框* box_link = dynamic_cast<C_行编辑框*>(box->m_Value.m_UI->m_部件);
		图元.颜色 = box_link->m_光标绘制.m_图元.颜色;
	}
	box->m_光标绘制.f_Draw(画布, 图元, E_笔刷类型::e_单色描边);

	auto 字体 = f_surface_get字体(*self->m_UIctx, S_UI主题::ui_默认字体);
	box->m_字符绘制.f_Draw(画布, &字体, box->m_框部件.m_属性);
	
}

static void f_行编辑框变换修改(C_Widget* self) {
	C_行编辑框* box = (C_行编辑框*)(self);

	auto& txt = box->m_Text;
	//if (box->m_Value.m_Type == E_值类型::e_Type_LineText && box->m_Value.m_Value) {
	//	txt = f_prop_Str(box->m_Value);
	//}

	mat3X2 Mat;
	Mat.row0 = { box->m_文本对齐偏移.x, 0};
	Mat.row1 = box->m_Size;
	Mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };
	box->m_字符绘制.f_alloc(1, 128);
	box->m_字符绘制.f_绘制文本({ Mat.row0 , Mat.row1 }, S_UI主题::uic_文字颜色, 0, txt, box->m_对齐方式, 1.01);
	

	int32 框选数量 = box->m_选取.结束行列.x - box->m_选取.开始行列.x;

	
	
	if (box->m_开启编辑 && 框选数量) {
		auto 字体 = f_surface_get字体(*self->m_UIctx, S_UI主题::ui_默认字体);

		box->m_框部件.f_alloc(2);

		auto 选取文本 = txt.substr(box->m_选取.开始行列.x+1, 框选数量);
		auto 偏移文本 = txt.substr(0, box->m_选取.开始行列.x+1);
		Mat.row0 = f_widget_get文字左对齐偏移位置(box->m_Size, txt, 字体, S_UI主题::ui_文字间隔);
		Mat.row0.y = 0;
		Mat.row0.x += box->m_文本对齐偏移.x + f_surface_get字符串宽度(字体, 偏移文本, S_UI主题::ui_文字间隔);
		Mat.row1.x = f_surface_get字符串宽度(字体, 选取文本, S_UI主题::ui_文字间隔);
		Mat.row1.y = box->m_Size.y;
		Mat.row2 = { DEF_Min(框选数量, S_UI主题::ui_面板圆角半径), 0 };
		box->m_框部件.f_set单色填充(1, Mat, S_UI主题::uic_值编辑框文字焦点背景, S_Widget预设图元::m_圆角矩形);
	}
	else {
		box->m_框部件.f_alloc(1);
		//std::cout<<"渲染参数.m_间接->m_Mem.m_大小 = "<<std::endl;
	}

	Mat.row0 = {};
	Mat.row1 = box->m_Size;
	Mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };
	box->m_框部件.f_set单色填充(0, Mat, box->m_颜色A, box->m_图元);
	
	
	if (box->m_开启编辑 && !框选数量) {
		box->m_光标绘制.f_alloc(1);

		mat3X2 mat;
		mat.row0 = box->g_光标绘制位置;
		mat.row1.x = 1;
		mat.row1.y = self->m_Size.y;
		mat.row2 = { 1, 0 };
		auto C = f_PackData4X8(S_UI主题::uic_行编辑框光标);
		box->m_光标绘制.f_set单色线(0, mat, { 1.0, C, C }, S_Widget预设图元::m_竖线, 2.0);

	}
	else {
		box->m_光标绘制.f_Close();
	}

}





Inline static void f_光标位置移动到选区(C_文本框* box) {
	box->m_选取.开始行列 = { int32(box->m_光标.x), int32(box->m_光标.y) };
	box->m_选取.结束行列 = box->m_选取.开始行列;
}

static uint8 f_拖拽是否从左开始(C_文本框* editBox) {
	if (editBox->m_选取.结束行列.y == editBox->m_选取.开始行列.y) {
		if (鼠标开始位置.x < 鼠标结束位置.x) {
			return 1;
		}
		else if (鼠标开始位置.x > 鼠标结束位置.x) {
			return 2;
		}
		else {
			return 0;
		}
	}
	else if (editBox->m_选取.结束行列.y > editBox->m_选取.开始行列.y) {
		return 1;
	}
	else if (editBox->m_选取.结束行列.y < editBox->m_选取.开始行列.y) {
		return 2;
	}
	return 0;
}


static void f_行编辑框从左置右开始框选(C_文本框* editBox) {
	选择开始位置 = f_widget_取鼠标在前光标位置(editBox, 鼠标开始位置, editBox->m_对齐方式, editBox->m_文本对齐偏移, editBox->m_Text);
	editBox->m_选取.开始行列.x = 选择开始位置.y;
	editBox->m_行选框左边和右边.x = 选择开始位置.x;

	//if (editBox->m_选取.结束行列.x < editBox->m_Text.size()) {
		选择结束位置 = f_widget_取鼠标在后光标位置(editBox, 鼠标结束位置, editBox->m_对齐方式, editBox->m_文本对齐偏移, editBox->m_Text);
		editBox->m_选取.结束行列.x = 选择结束位置.y;
		editBox->m_行选框左边和右边.y = 选择结束位置.x;
	//}
	editBox->m_光标.x = editBox->m_选取.结束行列.x;
	editBox->m_光标.y = editBox->m_选取.结束行列.y;
}


static void f_行编辑框从右置左开始框选(C_文本框* editBox) {
	选择结束位置 = f_widget_取鼠标在后光标位置(editBox, 鼠标开始位置, editBox->m_对齐方式, editBox->m_文本对齐偏移, editBox->m_Text);
	editBox->m_选取.结束行列.x = 选择结束位置.y;
	editBox->m_行选框左边和右边.y = 选择结束位置.x;

	//if (editBox->m_选取.开始行列.x < editBox->m_Text.size()) {
		选择开始位置 = f_widget_取鼠标在前光标位置(editBox, 鼠标结束位置, editBox->m_对齐方式, editBox->m_文本对齐偏移, editBox->m_Text);
		editBox->m_选取.开始行列.x = 选择开始位置.y;
		editBox->m_行选框左边和右边.x = 选择开始位置.x;
	//}
	editBox->m_光标.x = editBox->m_选取.开始行列.x;
	editBox->m_光标.y = editBox->m_选取.结束行列.y;
}



static void f_从左置右开始框选(C_文本框* editBox) {
	选择开始位置 = f_widget_取鼠标在前光标位置(editBox, 鼠标开始位置, editBox->m_对齐方式, editBox->m_文本对齐偏移, editBox->m_文档->m_文本块[editBox->m_选取.开始行列.y]);
	editBox->m_选取.开始行列.x = 选择开始位置.y;
	editBox->m_行选框左边和右边.x = 选择开始位置.x;

	if (editBox->m_选取.结束行列.y < editBox->m_文档->m_文本块.size()) {
		选择开始位置 = f_widget_取鼠标在后光标位置(editBox, 鼠标结束位置, editBox->m_对齐方式, editBox->m_文本对齐偏移, editBox->m_文档->m_文本块[editBox->m_选取.结束行列.y]);
		editBox->m_选取.结束行列.x = 选择开始位置.y;
		editBox->m_行选框左边和右边.y = 选择开始位置.x;
	}
	editBox->m_光标.x = editBox->m_选取.结束行列.x;
	editBox->m_光标.y = editBox->m_选取.结束行列.y;
}


static void f_从右置左开始框选(C_文本框* editBox) {
	选择开始位置 = f_widget_取鼠标在后光标位置(editBox, 鼠标开始位置, editBox->m_对齐方式, editBox->m_文本对齐偏移, editBox->m_文档->m_文本块[editBox->m_选取.开始行列.y]);
	editBox->m_选取.结束行列.x = 选择开始位置.y;
	editBox->m_行选框左边和右边.y = 选择开始位置.x;

	if (editBox->m_选取.结束行列.y < editBox->m_文档->m_文本块.size()) {
		选择开始位置 = f_widget_取鼠标在前光标位置(editBox, 鼠标结束位置, editBox->m_对齐方式, editBox->m_文本对齐偏移, editBox->m_文档->m_文本块[editBox->m_选取.结束行列.y]);
		editBox->m_选取.开始行列.x = 选择开始位置.y;
		editBox->m_行选框左边和右边.x = 选择开始位置.x;
	}
	editBox->m_光标.x = editBox->m_选取.开始行列.x;
	editBox->m_光标.y = editBox->m_选取.结束行列.y;
}

static E_事件是否传递 f_编辑框拖拽移动(C_Widget* self, const S_鼠标& 鼠标, S_拖放数据& data) {
	C_行编辑框* box = dynamic_cast<C_行编辑框*>(self);

	if (box->m_开启编辑 && box->m_选择开启) {
		box->m_绘制属性更新 = true;
		鼠标结束位置 = f_widget_get鼠标局部位置(C_Widget::g_鼠标.gPos, self);

		uint8 开始方式 = f_拖拽是否从左开始(box);
		if (开始方式 == 1) {
			f_行编辑框从左置右开始框选(box);
		}
		else if (开始方式 == 2) {
			f_行编辑框从右置左开始框选(box);
		}
		else {
			return E_事件是否传递::e_事件传递_继续;
		}

		if (box->mf_框选时回调) box->mf_框选时回调(self);
		//self->m_绘制属性更新 = true;
	}

	return E_事件是否传递::e_事件传递_继续;
}

static E_事件是否传递 f_编辑框开始拖拽(C_Widget* self, const S_鼠标& 鼠标, S_拖放数据& data) {
	C_行编辑框* editBox = dynamic_cast<C_行编辑框*>(self);
	if (editBox->f_使用子类拖放事件()) return E_事件是否传递::e_事件传递_继续;
	else editBox->mf_拖拽 = f_编辑框拖拽移动;

	鼠标开始位置 = f_widget_get鼠标局部位置(C_Widget::g_鼠标.gPos, self);

	editBox->f_set光标();
	editBox->m_选取.结束行列 = editBox->m_选取.开始行列;
	editBox->m_选择开启 = true;
	self->m_绘制属性更新 = true;

	g文本框选 = true;
	return E_事件是否传递::e_事件传递_继续;
}

static bool f_编辑框结束拖拽(C_Widget* self, struct C_Widget* 拾取的部件, S_拖放数据& data) {
	C_行编辑框* editBox = dynamic_cast<C_行编辑框*>(self);

	if (editBox->mf_框选后回调) editBox->mf_框选后回调(self);

	if (editBox->m_开启编辑) {
		C_文本框::g_选择文本ID区间.x = editBox->m_选取.开始行列.x;
		C_文本框::g_选择文本ID区间.y = editBox->m_选取.结束行列.x;
		
		editBox->mf_拖拽 = f_编辑框拖拽移动;
	}
	
	data.m_Type = E_拖放数据类型::e_文本选择;
	//editBox->f_输入完成();
	//editBox->m_选择开启 = false;
	g文本框选 = false;
	return true;
}








bool f_行编辑框_控制键输入(C_文本框* self, const S_键盘& ks) {
	C_行编辑框* box = dynamic_cast<C_行编辑框*>(self);
	//std::cout << "f_KS(ks, S_Input::e_KEY_小键盘数字键_回车) = " << int32(f_KS(ks, S_Input::e_KEY_小键盘数字键_回车)) << std::endl;
	if (f_KS(ks, S_InputKey::e_KEY_退格) == DEF_按键状态_放开) {
		f_行编辑框_退回字符(box);
	} 
	else if (f_KS(ks, S_InputKey::e_KEY_回车) == DEF_按键状态_放开 || f_KS(ks, S_InputKey::e_KEY_小键盘数字键_回车) == DEF_按键状态_放开) {
		self->f_输入完成();
	}
	else if (f_KS(ks, S_InputKey::e_KEY_左CTRL) == DEF_按键状态_按下中 && f_KS(ks, S_InputKey::e_KEY_C) == DEF_按键状态_放开) {
		box->f_Copy();
	}
	else if (f_KS(ks, S_InputKey::e_KEY_左CTRL) == DEF_按键状态_按下中 && f_KS(ks, S_InputKey::e_KEY_V) == DEF_按键状态_放开) {
		auto text = f_sys_get剪切板文本();
		std::vector<std::wstring> 分隔符 = { L"\r\n", L"\r", L"\n" };

		auto 分割后文本 = f_str_分割(text, L"\r\n");
		box->f_set插入文本(分割后文本);
		//std::wcout << "text = " << text << std::endl;
	}
	else if (f_KS(ks, S_InputKey::e_KEY_左CTRL) == DEF_按键状态_按下 || f_KS(ks, S_InputKey::e_KEY_左CTRL) == DEF_按键状态_放开) {
		
		return true;
	}
	else if (f_KS(ks, S_InputKey::e_KEY_左SHIFT) == DEF_按键状态_按下 || f_KS(ks, S_InputKey::e_KEY_左SHIFT) == DEF_按键状态_放开) {

		return true;
	}
	else if (f_KS(ks, S_InputKey::e_KEY_方向_左) == DEF_按键状态_按下) {
		if(box->m_光标.x >= 0) --box->m_光标.x;
	}
	else if (f_KS(ks, S_InputKey::e_KEY_方向_右) == DEF_按键状态_按下) {
		if(box->m_光标.x < box->m_Text.size()) ++box->m_光标.x;
	}
	else {
		return false;
	}
	
	box->f_set光标绘制坐标();
	return true;
}

vec2 f_行编辑框_计算光标位置(C_文本框* self, float32 文字间隔) {
	//return f_surface_get字符串宽度(*self->m_字体, self->m_Text.substr(0, C_文本框::g_选择文本ID区间.x), 文字间隔) + self->m_文本边偏移.x;
	return {};
}



void f_行编辑框_Ascii文本输入(C_行编辑框* box, const S_键盘& ks) {
	uint8 k = f_getKeyUn(ks);
	if (f_KS(ks, k) == DEF_按键状态_放开) {
		uint8 a = f_getDX按键AsciiKeyDown(k);
		if (!a) return;

		if (f_widget_是否处在输入法状态()) {
			ivec2 输入法位置 = { int32(C_文本框::g_光标绘制位置.x) , int32(C_文本框::g_光标绘制位置.y) };
			输入法位置.y += box->m_字行距 + box->m_字体->m_字号;
			输入法位置.x += box->m_GlobalLoc.x;
			输入法位置.y += box->m_GlobalLoc.y;
			f_widget_set编辑框输入法窗口位置(输入法位置);

			//f_widget_set编辑框输入法窗口位置(f_widget_get)
			auto str = f_widget_get输入法文本();
			
			if (str.size()) {
				f_edit_删除选取文本(box);

				if (box->m_光标.x > box->m_Text.size()) {
					box->m_Text.insert(box->m_Text.end(), str.begin(), str.end());
				}
				else {
					if (box->m_光标.x < box->m_Text.size()) {
						box->m_Text.insert(box->m_Text.begin() + (box->m_光标.x + 1), str.begin(), str.end());
					}
					else {
						box->m_Text.insert(box->m_Text.end(), str.begin(), str.end());
					}
				}
				
				
				box->m_光标.x += str.size();

				box->m_选取.开始行列.x = box->m_选取.结束行列.x = box->m_光标.x;
			}
			
		}
		else {
			if (f_widget_输入法是否有输入()) {
				f_widget_结束输入状态();
			}
			else {
				if (box->mf_文本过滤 && box->mf_文本过滤(box, a)) {
					f_edit_删除选取文本(box);
					/*int32 删除数量 = box->m_选取.结束行列.x - box->m_选取.开始行列.x;
					if (删除数量) {
						box->m_Text.erase(box->m_选取.开始行列.x + 1, 删除数量);
						box->m_光标.x = box->m_选取.开始行列.x;

						box->m_选取.开始行列.x = box->m_选取.结束行列.x = box->m_光标.x;
					}*/

					++box->m_光标.x;
					box->m_光标.x = DEF_Min(box->m_光标.x, box->m_Text.size());
					box->m_Text.insert(box->m_Text.begin() + box->m_光标.x, wchar_t(a));
				}
			}
		}

		//box->f_set光标();
		box->f_set光标绘制坐标();
	}
}

void f_行编辑框_输入法文本输入(C_行编辑框* box, const S_键盘& ks) {
	if (f_widget_是否处在输入法状态()) {
		if (f_widget_输入法是否有输入()) {
			goto To_正在输入;
		}
	}
	else {
	To_正在输入:
		//auto 中文 = f_widget_get输入法文本();
		f_行编辑框_Ascii文本输入(box, ks);
	}
	
}

void f_行编辑框_退回字符(C_行编辑框* box) {
	if (f_widget_输入法是否有输入()) {
		return;
	}
	int32 删除数量 = box->m_选取.结束行列.x - box->m_选取.开始行列.x;
	if (删除数量) {
		box->m_Text.erase(box->m_选取.开始行列.x + 1, 删除数量);
		box->m_光标.x = box->m_选取.开始行列.x;

		box->m_选取.开始行列.x = box->m_选取.结束行列.x = box->m_光标.x;
	}
	else {
		if (box->m_Text.size() && box->m_光标.x >= 0) {
			auto it = box->m_Text.begin() + DEF_Min(box->m_光标.x, box->m_Text.size() - 1);
			box->m_Text.erase(it);
			--box->m_光标.x;
		}
	}
}

bool f_行编辑框_删除选取(C_行编辑框* box) {
	int32 删除数量 = box->m_选取.结束行列.x - box->m_选取.开始行列.x;
	if (删除数量) {
		box->m_Text.erase(box->m_选取.开始行列.x + 1, 删除数量);
		box->m_光标.x = box->m_选取.开始行列.x;
		box->m_选取.开始行列.x = box->m_选取.结束行列.x;
	}

	return 删除数量;
}

void f_edit_删除选取文本(C_文本框* 文本框) {
	int32 删除数量 = 文本框->m_选取.结束行列.x - 文本框->m_选取.开始行列.x;

	if (删除数量) {
		文本框->m_Text.erase(文本框->m_选取.开始行列.x + 1, 删除数量);
		文本框->m_光标.x = 文本框->m_选取.开始行列.x;

		文本框->m_选取.开始行列.x = 文本框->m_选取.结束行列.x = 文本框->m_光标.x;
	}
}

	





static bool f_行编辑框_输入字符过滤(C_Widget* self, wchar_t c) {
	if (c >= 2) return true;
	else return false;
}



static bool f_行编辑框_按键按下(C_Widget* self, const S_键盘& ks) {
	C_行编辑框* editBox = dynamic_cast<C_行编辑框*>(self);

	if (editBox->m_开启编辑) {
		
		if (f_行编辑框_控制键输入(editBox, ks) == false) {
			f_行编辑框_Ascii文本输入(editBox, ks);

			editBox->m_绘制属性更新 = true;
		}
		
		
	}

	return true;
}

bool on_编辑框鼠标进入(C_Widget* self, const S_鼠标& 鼠标) {
	self->m_颜色A = self->m_颜色B + S_RGBA8UI{ 50, 50, 50, 127 };
	self->m_父部件->m_绘制属性更新 = true;
	return false;
}

bool on_编辑框鼠标退出(C_Widget* self, const S_鼠标& 鼠标) {
	self->m_颜色A = self->m_颜色B;
	self->m_父部件->m_绘制属性更新 = true;
	return false;
}







C_行编辑框::C_行编辑框(S_UI创建环境& ctx, const S_Props& prop): C_文本框(ctx, S_UI主题::ui_默认字体) {
	mf_开始拖拽 = f_编辑框开始拖拽;
	mf_结束拖拽 = f_编辑框结束拖拽;
	mf_拖拽		= f_编辑框拖拽移动;


	mf_键盘按键敲击	= f_行编辑框_按键按下;
	mf_文本过滤	= f_行编辑框_输入字符过滤;

	mf_DrawFun = f_行编辑框Draw;
	mf_变换修改 = f_行编辑框变换修改;
	mf_鼠标进入 = on_编辑框鼠标进入;
	mf_鼠标离开 = on_编辑框鼠标退出;

	m_图元 = S_Widget预设图元::m_圆角矩形;

	m_对齐方式 = E_对齐方式::e_左对齐;
	f_set对齐偏移();

	m_Value = prop;
}

C_行编辑框::~C_行编辑框() {
}

void C_行编辑框::f_绑定事件重置() {
	mf_开始拖拽 = f_编辑框开始拖拽;
	mf_结束拖拽 = f_编辑框结束拖拽;
	mf_拖拽		= f_编辑框拖拽移动;

	mf_键盘按键敲击 = f_行编辑框_按键按下;
	mf_文本过滤 = f_行编辑框_输入字符过滤;
}

bool C_行编辑框::f_使用子类拖放事件() {

	return false;
}

void C_行编辑框::f_set光标() {
	vec2 鼠标位置 = f_widget_get鼠标局部位置(C_Widget::g_鼠标.gPos, this);
	float32 行高 = (m_字体->m_字号 + m_字行距);

	f_set对齐偏移();

	vec2 i = f_widget_取鼠标在前光标位置(this, 鼠标位置, m_对齐方式, m_文本对齐偏移, m_Text);
	m_光标.x = i.y;
	m_光标.y = 0;
	
	f_set光标绘制坐标();
}

void C_行编辑框::f_开启输入() {
	
	C_文本框::g当前操作文本框 = this;
	f_set光标();
	
	if (m_开启编辑) {
		if (!g文本框选) {
			m_选取.开始行列 = m_光标;
			m_选取.结束行列 = m_选取.开始行列;
		}
	}
	else {
		m_选取.开始行列 = { -1,0 };
		if (m_Text.size()) {
			m_选取.结束行列.x = m_Text.size();
			m_选取.结束行列.y = 0;
		}
		else {
			m_选取.结束行列 = m_选取.开始行列;
		}
	}

	//C_Widget管理::m_当前锁定焦点部件 = this;
	m_开启编辑 = true;
}

void C_行编辑框::f_输入完成() {
	C_文本框::f_输入完成();

	switch (m_Value.m_Type) {
	case E_值类型::e_Type_Str:
	case E_值类型::e_Type_LineText:
		f_prop_Str(m_Value) = m_Text;
		break;
	}

	if (m_Value.m_UI && m_Value.m_UI->m_Update) {
		m_Value.m_UI->m_Update(m_Value);
	}
	
}

void C_行编辑框::f_Copy() {
	std::wstring 拷贝文本;

	int32 列开始 = 0;
	int32 列结束 = 0;
	
	列开始 = DEF_Min(m_选取.结束行列.x, m_选取.开始行列.x);
	列结束 = DEF_Max(m_选取.结束行列.x, m_选取.开始行列.x);

	拷贝文本 = m_Text.substr(列开始+1, 列结束 - 列开始);
	m_光标.x = 列结束;
	
	
	auto t = f_WStringToString(拷贝文本);
	f_sys_写到剪切板(t);
}

void C_行编辑框::f_set插入文本(std::vector<std::wstring> texts) {
	uint32 num = texts.size();
	
	m_Text.insert(m_光标.x + 1, texts[0]);
	m_光标.x += texts[0].size();

	f_光标位置移动到选区(this);
}

void C_行编辑框::f_set对齐偏移() {
	const auto& 字体 = f_surface_get字体库(*m_UIctx, S_UI主题::ui_默认字体);

	if (m_对齐方式 == E_对齐方式::e_据中对齐) {
		m_文本对齐偏移 = f_widget_get文字绘制据中偏移(m_Size, m_Text, 字体, S_UI主题::ui_文字间隔);
	}
	else if (m_对齐方式 == E_对齐方式::e_左对齐) {
		m_文本对齐偏移 = f_widget_get文字左对齐偏移位置(m_Size, m_Text, 字体, S_UI主题::ui_文字间隔);
		m_文本对齐偏移.x += m_文字边间距.x;
	}
	
	C_文本框::g_光标绘制位置.y = 0;
}

void f_ui_bind编辑框完成回调(C_Widget* self, fp_Widget文本输入完成 f输入完成) {
	dynamic_cast<C_文本框*>(self)->mf_文本输入完成 = f输入完成;
}

void f_ui_set行文本框文本(C_Widget* self, std::wstring text) {
	C_文本框* box = dynamic_cast<C_文本框*>(self);
	box->m_Text = text;
	box->m_绘制属性更新 = true;
}














/*static bool f_文本编辑框单击(C_Widget* self, const E_鼠标按钮& 按钮) {
	C_文本编辑框* editBox = dynamic_cast<C_文本编辑框*>(self);
	if (editBox->m_开启编辑) {
	}
	else {
		editBox->m_开启编辑 = true;
	}
	return true;
}*/


static bool f_文本编辑框_输入字符过滤(C_Widget* self, wchar_t ASCII) {
	auto* editBox = dynamic_cast<C_文本框*>(self);
	//std::cout << "A  input.m_Key.Keys[k] == " << int32(ASCII) << " _ " << std::endl;
	if (ASCII >= 32 && ASCII < 126) {
		uint32 num = editBox->m_Text.size();
		
		//std::cout << "input.m_Key.Keys[k] == " << int32(ASCII) << " _ " << std::endl;
		return true;
	}

	return false;
}


bool f_文本编辑框_控制键输入(C_文本框* self, const S_键盘& ks) {
	C_文本编辑框* editBox = dynamic_cast<C_文本编辑框*>(self);
	wchar_t 中 = 0;

	//std::cout << "f_KS(ks, S_Input::e_KEY_小键盘数字键_回车) = " << int32(f_KS(ks, S_Input::e_KEY_小键盘数字键_回车)) << std::endl;
	if (f_KS(ks, S_InputKey::e_KEY_退格) == DEF_按键状态_放开) {
		if (editBox->m_选取.开始行列.y - editBox->m_选取.结束行列.y || editBox->m_选取.开始行列.x - editBox->m_选取.结束行列.x) {
			editBox->f_删除字符();
		}
		else {
			if (editBox->m_光标.x > 0) {
				--editBox->m_光标.x;
				editBox->f_删除字符(editBox->m_光标);
			}
			else {
				if (editBox->m_光标.y > 0) {
					editBox->f_删除行(editBox->m_光标.y);
					--editBox->m_光标.y;

					editBox->m_光标.x = editBox->m_文档->m_文本块[editBox->m_光标.y].size();
				}
			}
		}

		editBox->m_选取.开始行列 = { int32(editBox->m_光标.x) , int32(editBox->m_光标.y) };
		editBox->m_选取.结束行列 = editBox->m_选取.开始行列;

		//self->m_光标位置.x = f_surface_get字符串宽度(*self->m_字体, self->m_Text.substr(0, C_文本框::g_选择文本ID区间.x), S_UI主题::ui_文字间隔) + self->m_文本边偏移.x;
		//if(self->mf_文本输入) self->mf_文本输入(self, self->m_Text);
		self->m_父部件->m_绘制属性更新 = true;
		中 = '\b';
	}
	else if (f_KS(ks, S_InputKey::e_KEY_回车) == DEF_按键状态_放开 || f_KS(ks, S_InputKey::e_KEY_小键盘数字键_回车) == DEF_按键状态_放开) {
		editBox->f_插入行(editBox->m_光标.y);
		++(editBox->m_光标.y);
		editBox->m_光标.x = 0;

		editBox->m_选取.开始行列 = { int32(editBox->m_光标.x) , int32(editBox->m_光标.y) };
		editBox->m_选取.结束行列 = editBox->m_选取.开始行列;

		self->m_父部件->m_绘制属性更新 = true;
		中 = '\n';
	}
	else if (f_KS(ks, S_InputKey::e_KEY_左CTRL) == DEF_按键状态_按下中 && f_KS(ks, S_InputKey::e_KEY_空格) == DEF_按键状态_放开) {
		self->m_父部件->m_绘制属性更新 = true;
		return true;
	}
	else {
		return false;
	}
	
	//if (editBox->mf_文本输入中) {
	//	editBox->f_字符相关输入(中);
	//}
	if (editBox->mf_文本输入) {
		std::wstring t;
		t = 中;
		editBox->mf_文本输入(editBox, t);
	}
	if (editBox->m_选择开启) {
		//C_Widget管理::m_当前锁定焦点部件 = self;
	}
	return true;
}


static bool f_文本编辑框_按键按下(C_Widget* self, const S_键盘& ks) {
	C_文本框* editBox = dynamic_cast<C_文本框*>(self);
	wchar_t ASCII = 0;
	bool 是否有输入 = false;
	//std::cout << "editBox->m_开启编辑 = " << editBox->m_开启编辑 << std::endl;
	//if (editBox->m_开启编辑) {
	if (1) {
		
		if (f_KS(ks, S_InputKey::e_KEY_左CTRL) == DEF_按键状态_按下中 && f_KS(ks, S_InputKey::e_KEY_C) == DEF_按键状态_放开) {
			editBox->f_Copy();
			是否有输入 = true;
			self->m_父部件->m_绘制属性更新 = true;
		} 
		else if (f_KS(ks, S_InputKey::e_KEY_左CTRL) == DEF_按键状态_按下中 && f_KS(ks, S_InputKey::e_KEY_V) == DEF_按键状态_放开) {
			auto text = f_sys_get剪切板文本();
			std::vector<std::wstring> 分隔符 = { L"\r\n", L"\r", L"\n" };

			auto 分割后文本 = f_str_分割(text, L"\r\n");
			editBox->f_set插入文本(分割后文本);
			是否有输入 = true;
			self->m_父部件->m_绘制属性更新 = true;
			//std::wcout << "text = " << text << std::endl;
		}
		else if (f_KS(ks, S_InputKey::e_KEY_方向_左) == DEF_按键状态_放开) {
			if (editBox->m_光标.x) {
				--editBox->m_光标.x;
			}
			else {
				//editBox->m_光标.x = editBox->m_文档->m_文本块[editBox->m_光标.y].size();
				goto To_光标上移;
			}
			f_光标位置移动到选区(editBox);
			是否有输入 = true;
		}
		else if (f_KS(ks, S_InputKey::e_KEY_方向_右) == DEF_按键状态_放开) {
			if (editBox->m_光标.x < editBox->m_文档->m_文本块[editBox->m_光标.y].size()) {
				++editBox->m_光标.x;
			}
			else {
				editBox->m_光标.x = 0;
				goto To_光标下移;
			}
			f_光标位置移动到选区(editBox);
			是否有输入 = true;
		}
		else if (f_KS(ks, S_InputKey::e_KEY_方向_上) == DEF_按键状态_放开) {
		To_光标上移:
			if (editBox->m_光标.y) {
				--editBox->m_光标.y;
				if (editBox->m_光标.x > editBox->m_文档->m_文本块[editBox->m_光标.y].size()) {
					editBox->m_光标.x = editBox->m_文档->m_文本块[editBox->m_光标.y].size();
				}
			}
			f_光标位置移动到选区(editBox);
			是否有输入 = true;
		}
		else if (f_KS(ks, S_InputKey::e_KEY_方向_下) == DEF_按键状态_放开) {
			To_光标下移:
			if (editBox->m_光标.y + 1 < editBox->m_文档->m_文本块.size()) {
				++editBox->m_光标.y;

				if (editBox->m_光标.x > editBox->m_文档->m_文本块[editBox->m_光标.y].size()) {
					editBox->m_光标.x = editBox->m_文档->m_文本块[editBox->m_光标.y].size();
				}
			}
			f_光标位置移动到选区(editBox);
			是否有输入 = true;
		}
		else if (f_KS(ks, S_InputKey::e_KEY_TAB) == DEF_按键状态_放开) {
			editBox->f_插入字符('\t', editBox->m_光标);
			++(editBox->m_光标.x);

			editBox->m_选取.开始行列 = { int32(editBox->m_光标.x) , int32(editBox->m_光标.y) };
			editBox->m_选取.结束行列 = editBox->m_选取.开始行列;

			ASCII = '\t';
			是否有输入 = true;
		}
		else if (f_文本编辑框_控制键输入(editBox, ks) == false) {
			auto 输入法文本 = f_widget_get输入法文本();

			if (输入法文本.empty()) {
				uint8 k = f_getKeyUn(ks);
				if (k) {
					//std::wcout << "输入" << std::endl;
					if (f_KS(ks, k) == DEF_按键状态_放开) {
						
						ASCII = f_getDX按键AsciiKeyDown(k);
						//std::cout<<"f_数值编辑框_按键按下 = "<<int32(a)<<" K="<<k<<std::endl;
						if (editBox->mf_文本过滤 && editBox->mf_文本过滤(editBox, ASCII)) {
							editBox->f_插入字符(ASCII, editBox->m_光标);
							++(editBox->m_光标.x);
							//editBox->m_Text.insert(C_文本框::g_选择文本ID区间.x, 1, a);
							++C_文本框::g_选择文本ID区间.x;


							if (f_widget_是否处在输入法状态()) {
								++(editBox->m_选取.结束行列.x);
							}
							else {
								editBox->m_选取.开始行列 = { int32(editBox->m_光标.x) , int32(editBox->m_光标.y) };
								editBox->m_选取.结束行列 = editBox->m_选取.开始行列;
							}


							self->m_父部件->m_绘制属性更新 = true;
						}

					}

					是否有输入 = true;
				}
			}
			else {
				editBox->f_删除字符();
				editBox->f_set插入文本({ 输入法文本 });
				//std::cout << "f_get系统字符编码名称 = " << f_get系统字符编码名称() << std::endl;
			}
			
			
		}
		else {
			是否有输入 = true;
			//return true;
		}
		
		
		


		//计算光标位置
		C_文本框::g_光标绘制位置.x = f_surface_get字符串宽度(*editBox->m_字体, editBox->m_文档->m_文本块[editBox->m_光标.y].substr(0, editBox->m_光标.x), S_UI主题::ui_文字间隔) + editBox->m_文本对齐偏移.x;
		C_文本框::g_光标绘制位置.y = (editBox->m_字体->m_字号 + editBox->m_字行距) * editBox->m_光标.y;

		C_文本框::g_光标绘制位置.x += editBox->m_Pos.x;
		C_文本框::g_光标绘制位置.y += editBox->m_Pos.y;

		ivec2 输入法位置 = { int32(C_文本框::g_光标绘制位置.x) , int32(C_文本框::g_光标绘制位置.y) };
		输入法位置.y += editBox->m_字行距 + editBox->m_字体->m_字号;
		f_widget_set编辑框输入法窗口位置(输入法位置);

		if (是否有输入 && editBox->mf_文本输入) {
			std::wstring t;
			t = ASCII;
			editBox->mf_文本输入(editBox, t);
		}
	}

	
	return true;
}



static E_事件是否传递 f_文本编辑框开始拖拽(C_Widget* self, const S_鼠标& 鼠标, S_拖放数据& data) {
	C_文本编辑框* editBox = dynamic_cast<C_文本编辑框*>(self);
	//if (editBox->f_使用子类拖放事件()) return true;
	float32 行高 = (editBox->m_字体->m_字号 + editBox->m_字行距);
	鼠标开始位置 = f_widget_get鼠标局部位置(C_Widget::g_鼠标.gPos, self);

	//editBox->m_选取.开始行列.y = (鼠标位置.y + 行高 * 0.5) / 行高;
	editBox->m_选取.开始行列.y = (鼠标开始位置.y) / 行高;
	if (editBox->m_选取.开始行列.y < editBox->m_文档->m_文本块.size()) {
		//选择开始位置 = f_widget_取前光标位置(editBox, 鼠标开始位置, editBox->m_对齐方式, editBox->m_文本边偏移, editBox->m_文档->m_文本块[editBox->m_选取.开始行列.y]);
		//editBox->m_选取.开始行列.x = 选择开始位置.y;
	}
	else {
		editBox->m_选取.开始行列.y = editBox->m_文档->m_文本块.size() - 1;
	}

	//std::cout << "begin" << std::endl;
	editBox->m_选取.结束行列 = editBox->m_选取.开始行列;


	//if (editBox->mf_框选时回调) editBox->mf_框选时回调(self);


	editBox->m_选择开启 = true;
	self->m_绘制属性更新 = true;

	return E_事件是否传递::e_事件传递_继续;
}


static E_事件是否传递 f_文本编辑框拖拽(C_Widget* self, const S_鼠标& 鼠标, S_拖放数据& data) {
	C_文本编辑框* editBox = dynamic_cast<C_文本编辑框*>(self);
	//if (!editBox->m_开启编辑) return true;
	if (editBox->m_选择开启) {
	//if (editBox->m_开启编辑 && editBox->m_选择开启) {
		鼠标结束位置 = f_widget_get鼠标局部位置(C_Widget::g_鼠标.gPos, self);
		float32 行高 = (editBox->m_字体->m_字号 + editBox->m_字行距);

		//editBox->m_选取.结束行列.y = (鼠标位置.y + 行高) / 行高;
		editBox->m_选取.结束行列.y = (鼠标结束位置.y) / 行高;
		editBox->m_选取.结束行列.y = DEF_Min(editBox->m_选取.结束行列.y, editBox->m_文档->m_文本块.size() - 1);


		if (editBox->m_选取.结束行列.y == editBox->m_选取.开始行列.y) {
			if (鼠标开始位置.x < 鼠标结束位置.x) {
				goto To_从左置右;
			}
			else if (鼠标开始位置.x > 鼠标结束位置.x) {
				goto To_从右置左;
			}
			else {
				return E_事件是否传递::e_事件传递_继续;
			}
		}
		else if (editBox->m_选取.结束行列.y > editBox->m_选取.开始行列.y) {
			goto To_从左置右;
		}
		else if (editBox->m_选取.结束行列.y < editBox->m_选取.开始行列.y) {
			goto To_从右置左;
		}

		


	To_从左置右:
		选择开始位置 = f_widget_取鼠标在前光标位置(editBox, 鼠标开始位置, editBox->m_对齐方式, editBox->m_文本对齐偏移, editBox->m_文档->m_文本块[editBox->m_选取.开始行列.y]);
		editBox->m_选取.开始行列.x = 选择开始位置.y;

		if (editBox->m_选取.结束行列.y < editBox->m_文档->m_文本块.size()) {
			选择开始位置 = f_widget_取鼠标在后光标位置(editBox, 鼠标结束位置, editBox->m_对齐方式, editBox->m_文本对齐偏移, editBox->m_文档->m_文本块[editBox->m_选取.结束行列.y]);
			editBox->m_选取.结束行列.x = 选择开始位置.y;
		}
		editBox->m_光标.x = editBox->m_选取.结束行列.x;
		editBox->m_光标.y = editBox->m_选取.结束行列.y;

		goto To_执行外部回调;


	To_从右置左:
		选择开始位置 = f_widget_取鼠标在后光标位置(editBox, 鼠标开始位置, editBox->m_对齐方式, editBox->m_文本对齐偏移, editBox->m_文档->m_文本块[editBox->m_选取.开始行列.y]);
		editBox->m_选取.结束行列.x = 选择开始位置.y;

		if (editBox->m_选取.结束行列.y < editBox->m_文档->m_文本块.size()) {
			选择开始位置 = f_widget_取鼠标在前光标位置(editBox, 鼠标结束位置, editBox->m_对齐方式, editBox->m_文本对齐偏移, editBox->m_文档->m_文本块[editBox->m_选取.结束行列.y]);
			
			editBox->m_选取.开始行列.x = 选择开始位置.y;
		}
		editBox->m_光标.x = editBox->m_选取.开始行列.x;
		editBox->m_光标.y = editBox->m_选取.结束行列.y;




	To_执行外部回调:
		//std::cout << "AeditBox->m_选取.开始行列 = " << editBox->m_选取.开始行列.x << " : " << editBox->m_选取.开始行列.y << std::endl;
		//std::cout << "BeditBox->m_选取.结束行列 = " << editBox->m_选取.结束行列.x << " : " << editBox->m_选取.结束行列.y << std::endl;
		if (editBox->mf_框选时回调) editBox->mf_框选时回调(self);

		self->m_绘制属性更新 = true;
	}

	return E_事件是否传递::e_事件传递_继续;
}

static bool f_文本编辑框结束拖拽(C_Widget* self, struct C_Widget* 拾取的部件, S_拖放数据& data) {
	C_文本编辑框* editBox = dynamic_cast<C_文本编辑框*>(self);

	if (editBox->mf_文本输入完成) editBox->mf_文本输入完成(self);
	if (editBox->m_开启编辑) {
		if (C_文本框::g_选择文本ID区间.y < C_文本框::g_选择文本ID区间.x) {
			uint32 temp = C_文本框::g_选择文本ID区间.y;
			C_文本框::g_选择文本ID区间.y = C_文本框::g_选择文本ID区间.x;
			C_文本框::g_选择文本ID区间.x = temp;
		}
		//g当前插入位置 = g_选择文本ID区间.x;
	}
	else {

	}
	//std::cout << "extent.x = end" << std::endl;
	//editBox->m_选择开启 = false;
	return true;
}

static bool on_编辑框鼠标按键(C_Widget* self, const E_鼠标按钮& 按钮) {
	//std::cout << "双击" << std::endl;
	C_文本编辑框* editBox = dynamic_cast<C_文本编辑框*>(self);

	auto& str = editBox->m_文档->m_文本块[editBox->m_光标.y];
	int32 num = str.size();

	int32 begin = editBox->m_光标.x + 1;
	int32 end = editBox->m_光标.x;
	for (int32 i = editBox->m_光标.x; i >= 0; --i) {
		switch (str[i]) {
		case '.':
		case '-':
		case '+':
		case '*':
		case '/':
		case '[':
		case ']':
		case '{':
		case '}':
		case '(':
		case ')':
		case '"':
		case ';':
		case ':':
		case ' ':
		case '<':
		case '>':
		case ',':
		case '=':
		case '\t':
			goto To_后段计算;
			break;
		default:
			--begin;
			break;
		}
	}

	To_后段计算:
	for (int32 i = editBox->m_光标.x; i < num; ++i) {
		switch (str[i]) {
		case '.':
		case '-':
		case '+':
		case '*':
		case '/':
		case '[':
		case ']':
		case '{':
		case '}':
		case '(':
		case ')':
		case '"':
		case ';':
		case ':':
		case ' ':
		case '<':
		case '>':
		case ',':
		case '=':
		case '\t':
			goto To_end;
			break;
		default:
			++end;
			break;
		}
	}

To_end:
	if (begin < 0) begin = 0;

	editBox->m_选取.开始行列.x = begin;
	editBox->m_选取.开始行列.y = editBox->m_光标.y;
	editBox->m_选取.结束行列.x = end;
	editBox->m_选取.结束行列.y = editBox->m_光标.y;

	editBox->m_光标.x = end;
	//self->m_绘制属性更新 = true;
	if (editBox->mf_框选时回调) editBox->mf_框选时回调(self);
	return true;
}


C_文本编辑框::C_文本编辑框(S_UI创建环境& ctx, std::string 字体名称) : C_文本框(ctx, 字体名称) {
	m_对齐方式 = E_对齐方式::e_左对齐;

	mf_文本过滤 = f_文本编辑框_输入字符过滤;

	mf_鼠标按键双击 = on_编辑框鼠标按键;

	mf_键盘按键敲击 = f_文本编辑框_按键按下;
	mf_开始拖拽 = f_文本编辑框开始拖拽;
	mf_结束拖拽 = f_文本编辑框结束拖拽;
	mf_拖拽 = f_文本编辑框拖拽;

	
	mf_框选时回调 = nullptr;
	mf_框选后回调 = nullptr;


	m_文档->m_文本块.push_back(L"");
	m_文档->m_Color.push_back({});

	m_文本对齐偏移.x = 50 * ctx.m_DPI;

}

C_文本编辑框::~C_文本编辑框() {
}

void C_文本编辑框::f_插入字符(wchar_t t, ivec2 pos) {
	if (m_文档->m_文本块.size() > pos.y) {
		if (m_文档->m_文本块[pos.y].size() > pos.x) {
			m_文档->m_文本块[pos.y].insert(m_文档->m_文本块[pos.y].begin() + pos.x, t);
			m_文档->m_Color[pos.y].insert(m_文档->m_Color[pos.y].begin() + pos.x, S_UI主题::uic_文字颜色);
		}
		else {
			m_文档->m_文本块[pos.y].push_back(t);
			m_文档->m_Color[pos.y].push_back(S_UI主题::uic_文字颜色);
		}
	}
	//++m_光标.x;
}

void C_文本编辑框::f_删除字符(ivec2 pos) {
	if (m_文档->m_文本块.size() > pos.y) {
		if (m_文档->m_文本块[pos.y].size() > pos.x) {
			m_文档->m_文本块[pos.y].erase(pos.x, 1);
			m_文档->m_Color[pos.y].erase(m_文档->m_Color[pos.y].begin() + pos.x);
		}
		else {
			m_文档->m_文本块[pos.y].pop_back();
			m_文档->m_Color[pos.y].pop_back();
		}
	}
}

void C_文本编辑框::f_插入行(uint32 pos)
{
	if (m_文档->m_文本块.size() <= pos) {
		//m_文档->m_文本块.push_back(L"\n");
		//m_文档->m_Color.push_back({ S_UI主题::uic_菜单文字颜色 });
		m_文档->m_文本块.push_back({});
		m_文档->m_Color.push_back({});
	}
	else {
		auto 文本前半部分 = m_文档->m_文本块[pos].substr(0, m_光标.x);
		auto 文本后半部分 = m_文档->m_文本块[pos].substr(m_光标.x, -1);

		m_文档->m_文本块[pos] = 文本前半部分;
		m_文档->m_文本块.insert(m_文档->m_文本块.begin() + pos + 1, 文本后半部分);

		m_文档->m_Color[pos] = std::vector<S_RGBA8UI>(文本前半部分.size(), S_UI主题::uic_文字颜色);
		m_文档->m_Color.insert(m_文档->m_Color.begin() + pos + 1, std::vector<S_RGBA8UI>(文本后半部分.size(), S_UI主题::uic_文字颜色));
	}

	
	f_添加行大小(1);

}

void C_文本编辑框::f_删除行(uint32 pos)
{
	if (m_文档->m_文本块.size() > pos) {
		m_文档->m_文本块.erase(m_文档->m_文本块.begin() + pos);
		m_文档->m_Color.erase(m_文档->m_Color.begin() + pos);
	}
	else {
		m_文档->m_文本块.pop_back();
		m_文档->m_Color.pop_back();
	}


	if (m_文档->m_文本块.size() > 10) {
		vec2 size = m_Size;
		size.y -= m_字行距 + m_字体->m_字号;
		f_setSize(size);
	}
	
}

template<typename T1> 
static void f_块文档删除(T1& 块, const S_文本选框区域ID& 区域) {
	auto beginA = 块[区域.开始行列.y].begin() + 区域.开始行列.x;
	auto beginB = 块[区域.结束行列.y].begin() + 区域.结束行列.x;
	块[区域.开始行列.y].erase(beginA, 块[区域.开始行列.y].end());
	//块[区域.结束行列.y].erase(块[区域.结束行列.y].begin(), beginB);
	//块[区域.开始行列.y].assign(块[区域.开始行列.y].end(), beginB, 块[区域.结束行列.y].end());
	块[区域.开始行列.y].insert(块[区域.开始行列.y].end(), beginB, 块[区域.结束行列.y].end());

	uint32 num = 区域.结束行列.y - 区域.开始行列.y;
	for (uint32 i = 0; i < num; ++i) {
		块.erase(块.begin() + (区域.开始行列.y + 1));
	}
}


void C_文本编辑框::f_删除字符()
{
	if (m_选取.结束行列.y == m_选取.开始行列.y) {
		auto begin = m_文档->m_文本块[m_选取.开始行列.y].begin() + m_选取.开始行列.x;
		auto end = m_文档->m_文本块[m_选取.开始行列.y].begin() + m_选取.结束行列.x;
		m_文档->m_文本块[m_选取.开始行列.y].erase(begin, end);

		m_光标.x = m_选取.开始行列.x;
		m_选取.结束行列 = m_选取.开始行列;
	}
	else if (m_选取.结束行列.y >= m_选取.开始行列.y) {
		
		f_块文档删除(m_文档->m_文本块, m_选取);
		f_块文档删除(m_文档->m_Color, m_选取);

		m_选取.结束行列 = m_选取.开始行列;
	}
	else {
		S_文本选框区域ID 选取 = m_选取;
		选取.开始行列.y = DEF_Min(m_选取.开始行列.y, m_选取.结束行列.y);
		选取.结束行列.y = DEF_Max(m_选取.开始行列.y, m_选取.结束行列.y);

		f_块文档删除(m_文档->m_文本块, 选取);
		f_块文档删除(m_文档->m_Color, 选取);

		m_选取.开始行列 = 选取.开始行列;
		m_选取.结束行列 = 选取.开始行列;
	}

	m_光标.x = m_选取.开始行列.x;
	m_光标.y = m_选取.开始行列.y;
}

void C_文本编辑框::f_添加行大小(uint32 num)
{
	float32 行高度 = (m_字行距 + m_字体->m_字号);
	vec2 size = m_Size;
	size.y += 行高度 * num;
	f_setSize(size);



	if (m_光标.y * 行高度 + m_Pos.y + 行高度 > m_父部件->m_Size.y - S_UI主题::ui_滚动条厚度) {
		size = m_Pos;
		size.y -= 行高度 * num;
		f_setPos(size);
	}
	
}

void C_文本编辑框::f_减少行大小(uint32 num)
{
	float32 行高度 = (m_字行距 + m_字体->m_字号);
	vec2 size = m_Size;
	size.y -= 行高度 * num;
	f_setSize(size);


	if (m_光标.y * 行高度 + m_Pos.y + 行高度 > m_父部件->m_Size.y - S_UI主题::ui_滚动条厚度) {
		size = m_Pos;
		size.y += 行高度 * num;
		f_setPos(size);
	}

}

void C_文本编辑框::f_set光标()
{
	vec2 鼠标位置 = f_widget_get鼠标局部位置(C_Widget::g_鼠标.gPos, this);
	float32 行高 = (m_字体->m_字号 + m_字行距);

	m_光标.y = (鼠标位置.y) / 行高;
	m_光标.y = DEF_Min(m_光标.y, m_文档->m_文本块.size() - 1);

	m_选取.结束行列 = m_选取.开始行列;

	//i.y 为字符索引位置
	auto i = f_widget_取鼠标在前光标位置(this, 鼠标位置, m_对齐方式, m_文本对齐偏移, m_文档->m_文本块[m_光标.y]);
	m_光标.x = i.y;

	
	C_文本框::g_光标绘制位置.x = f_surface_get字符串宽度(*m_字体, m_文档->m_文本块[m_光标.y].substr(0, m_光标.x), S_UI主题::ui_文字间隔) + m_文本对齐偏移.x;
	C_文本框::g_光标绘制位置.y = (m_字体->m_字号 + m_字行距) * m_光标.y;

	C_文本框::g_光标绘制位置.x += m_Pos.x;
	C_文本框::g_光标绘制位置.y += m_Pos.y;
}

void C_文本编辑框::f_set插入文本(std::vector<std::wstring> texts) {
	uint32 num = texts.size();
	if (num >= 1) {
		--num;
	}
	 
	 
	auto 拆分文本 = m_文档->m_文本块[m_光标.y];
	auto 源文本前部分拆分 = 拆分文本.substr(0, m_光标.x);
	auto 源文本后部分拆分 = 拆分文本.substr(m_光标.x, -1);

	m_光标.x = 源文本前部分拆分.size() + texts[0].size();


	texts[0].insert(0, 源文本前部分拆分);
	texts[num].insert(texts[num].size(), 源文本后部分拆分);
	

	m_文档->m_文本块[m_光标.y] = texts[0];
	m_文档->m_Color[m_光标.y] = std::vector<S_RGBA8UI>(texts[0].size(), S_UI主题::uic_文字颜色);
	for (uint32 i = 1; i < num; ++i) {
		uint32 字符数量 = texts[i].size();
		std::vector<S_RGBA8UI> color(字符数量, S_UI主题::uic_文字颜色);

		m_文档->m_文本块.insert(m_文档->m_文本块.begin() + m_光标.y + i, texts[i]);
		m_文档->m_Color.insert(m_文档->m_Color.begin() + m_光标.y + i, color);

	}
	
	
	if (num) {
		m_光标.y += num - 1;
		//m_光标.x = texts[num].size();
		m_光标.x = texts.back().size();
	}

	f_光标位置移动到选区(this);
	
	f_添加行大小(num);
}

void C_文本编辑框::f_Copy() {
	uint32 开始行 = DEF_Min(m_选取.结束行列.y, m_选取.开始行列.y);
	uint32 结束行 = DEF_Max(m_选取.结束行列.y, m_选取.开始行列.y);
	int32 num = 结束行 - 开始行;


	std::vector<std::wstring> 切片;

	uint32 列开始 = 0;
	uint32 列结束 = 0;
	if (num < 1) {
		列开始 = DEF_Min(m_选取.结束行列.x, m_选取.开始行列.x);
		列结束 = DEF_Max(m_选取.结束行列.x, m_选取.开始行列.x);

		切片.push_back(m_文档->m_文本块[开始行].substr(列开始, 列结束 - 列开始));
		m_光标.x = 列结束;
	}
	else {
		
		/*if (m_选取.结束行列.y > m_选取.开始行列.y) {
			列开始 = m_选取.开始行列.x;
			列结束 = m_选取.结束行列.x;
		}
		else {
			列开始 = m_选取.结束行列.x;
			列结束 = m_选取.开始行列.x;
		}*/
		列开始 = m_选取.开始行列.x;
		列结束 = m_选取.结束行列.x;

		
		切片.push_back(m_文档->m_文本块[开始行].substr(列开始, -1));
		
		for (int32 i = 1; i < num; ++i) {
			切片.push_back(m_文档->m_文本块[开始行 + i]);
		}

		切片.push_back(m_文档->m_文本块[结束行].substr(0, 列结束));

		m_光标.x = 列结束;
		m_光标.y = 结束行;
	}

	

	auto t = f_WString组ToString(切片);
	f_sys_写到剪切板(t);



	/*C_文本框::g_光标位置.x = f_surface_get字符串宽度(*m_字体, m_文档->m_文本块[m_光标.y].substr(0, m_光标.x), S_UI主题::ui_文字间隔) + m_文本边偏移.x;
	C_文本框::g_光标位置.y = (m_字体->m_字号 + m_字行距) * m_光标.y;
	C_文本框::g_光标位置.x += m_Pos.x;
	C_文本框::g_光标位置.y += m_Pos.y;*/
}

void C_文本编辑框::f_粘贴() {

}








